package com.qh.resourcehub.program.netmapping.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qh.resourcehub.program.dto.NetMappingAssessmentDto;
import com.qh.resourcehub.program.dto.NetMappingDto;
import com.qh.resourcehub.program.dto.NetMappingHostDto;
import com.qh.resourcehub.program.dto.NetMappingPortDto;
import com.qh.resourcehub.program.entity.*;
import com.qh.resourcehub.program.mapper.*;
import com.qh.resourcehub.program.netmapping.service.NetMappingService;
import com.qh.resourcehub.program.vo.NetMappingAssessmentVo;
import com.qh.resourcehub.program.vo.NetMappingHostVo;
import com.qh.resourcehub.program.vo.NetMappingPortVo;
import com.qh.resourcehub.program.vo.NetMappingVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: Y6
 * @date: 2025/4/18 15:17
 */
@Service
public class NetMappingServiceImpl implements NetMappingService {
    @Autowired
    private NetMappingMapper Mapper;

    @Autowired
    private NetMappingHostMapper netMappingHostMapper;

    @Autowired
    private NetMappingAssessmentMapper netMappingAssessmentMapper;

    @Autowired
    private NetMappingPortMapper netMappingPortMapper;

    @Autowired
    private ApproveProcessMapper approveProcessMapper;

    @Autowired
    private ApproveProcessRecordMapper approveProcessRecordMapper;
    @Override
    public int ApplicationSave(NetMappingDto dataDto) {
        int result = 0;
        if (!StringUtils.isEmpty(dataDto.getApplyUser()) && StringUtils.isEmpty(dataDto.getInfoId())){
            dataDto.setInfoId(UUID.randomUUID().toString().replace("-", ""));
            //新增流程表
            ApproveProcessDO approveProcessDO=new ApproveProcessDO();
            approveProcessDO.setInfoId(dataDto.getInfoId());//信息id
            approveProcessDO.setProcessStatus("00");//待提交
            approveProcessDO.setProcessTime(new Date());
            approveProcessDO.setProcessUser(dataDto.getApplyUser());
            approveProcessDO.setInfoType("5");
            approveProcessDO.setProcessId(UUID.randomUUID().toString().replace("-", ""));
            approveProcessDO.setProcessRecordId(UUID.randomUUID().toString().replace("-", ""));
            approveProcessMapper.insert(approveProcessDO);
            NetMappingDO dataDo=new NetMappingDO();
            BeanUtils.copyProperties(dataDto, dataDo);
            //新增基础表
            result=Mapper.insert(dataDo);
            List<NetMappingAssessmentDto> netMappingAssessmentDtos=dataDto.getAssessments();
            List<NetMappingHostDto> hosts = dataDto.getHosts();
            List<NetMappingPortDto> ports = dataDto.getPorts();
            if (ObjectUtil.isNotEmpty(netMappingAssessmentDtos)){
                for (NetMappingAssessmentDto assessment : netMappingAssessmentDtos) {
                    NetMappingAssessmentDO assessmentDo=new NetMappingAssessmentDO();
                    assessmentDo.setInfoId(dataDto.getInfoId());
                    assessmentDo.setBusinessSystemName(assessment.getBusinessSystemName());
                    assessmentDo.setInternalIp(assessment.getInternalIp());
                    assessmentDo.setSecurityScore(assessment.getSecurityScore());
                    assessmentDo.setIsPass(assessment.getIsPass());
                    assessmentDo.setId(UUID.randomUUID().toString().replace("-", ""));
                    netMappingAssessmentMapper.insert(assessmentDo);
                }
            } if (ObjectUtil.isNotEmpty(hosts)) {
                for (NetMappingHostDto host : hosts) {
                    NetMappingHostDO hostDo=new NetMappingHostDO();
                    hostDo.setInfoId(dataDto.getInfoId());
                    hostDo.setOsType(host.getOsType());
                    hostDo.setServerUsage(host.getServerUsage());
                    hostDo.setInternalIp(host.getInternalIp());
                    hostDo.setMacAddress(host.getMacAddress());
                    hostDo.setDatabaseInfo(host.getDatabaseInfo());
                    hostDo.setMiddlewareInfo(host.getMiddlewareInfo());
                    hostDo.setInternetAccessFlag(host.getInternetAccessFlag());
                    hostDo.setId(UUID.randomUUID().toString().replace("-", ""));
                    netMappingHostMapper.insert(hostDo);
                }
            } if (ObjectUtil.isNotEmpty(ports)) {
                for (NetMappingPortDto port : ports) {
                    NetMappingPortDO portDo=new NetMappingPortDO();
                    portDo.setInfoId(dataDto.getInfoId());
                    portDo.setPortNumber(port.getPortNumber());
                    portDo.setProtocolType(port.getProtocolType());
                    portDo.setPortUsage(port.getPortUsage());
                    portDo.setId(UUID.randomUUID().toString().replace("-", ""));
                    netMappingPortMapper.insert(portDo);
                }
            }

        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int ApplicationUpdata(NetMappingDto dataDto) {
        int result = 0;
        //设置状态
        if (!StringUtils.isEmpty(dataDto.getApplyUser()) && !StringUtils.isEmpty(dataDto.getInfoId())) {
            //新增流程表
            NetMappingDO dataDo = new NetMappingDO();
            BeanUtils.copyProperties(dataDto, dataDo);
            //新增基础表
            LambdaQueryWrapper<NetMappingDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(NetMappingDO::getInfoId, dataDto.getInfoId());
            result = Mapper.update(dataDo, queryWrapper);
            updateNetMappingData(dataDto);
        }
        if (!ObjectUtil.isEmpty(dataDto.getProcessStatus()) && dataDto.getProcessStatus().equals("010")) {
            //修改流程表状态为00待提交
            LambdaUpdateWrapper<ApproveProcessDO> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(ApproveProcessDO::getProcessId, dataDto.getProcessId())
                    .set(ApproveProcessDO::getProcessStatus, "00");
            int updateCount = approveProcessMapper.update(null, updateWrapper);
            //并且删除对应流程信息表信息
            LambdaQueryWrapper<ApproveProcessRecordDO> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(ApproveProcessRecordDO::getRecordId, dataDto.getProcessId());
            int de = approveProcessRecordMapper.delete(deleteWrapper);
            updateNetMappingData(dataDto);
            return (updateCount > 0 || de > 0) ? 1 : 0;
        }
        return result;
    }
    public void updateNetMappingData(NetMappingDto dataDto) {
        List<NetMappingAssessmentDto> netMappingAssessmentDtos = dataDto.getAssessments();
        List<NetMappingHostDto> hosts = dataDto.getHosts();
        List<NetMappingPortDto> ports = dataDto.getPorts();
        // Assessment 处理逻辑
        List<NetMappingAssessmentDO> dbAssessmentList = netMappingAssessmentMapper.selectList(
                new LambdaQueryWrapper<NetMappingAssessmentDO>()
                        .eq(NetMappingAssessmentDO::getInfoId, dataDto.getInfoId())
        );
        Set<String> dbAssessmentIds = dbAssessmentList.stream()
                .map(NetMappingAssessmentDO::getId)
                .collect(Collectors.toSet());
        Set<String> incomingAssessmentIds = new HashSet<>();

        if (ObjectUtil.isNotEmpty(netMappingAssessmentDtos)) {
            for (NetMappingAssessmentDto assessment : netMappingAssessmentDtos) {
                NetMappingAssessmentDO assessmentDo = new NetMappingAssessmentDO();
                BeanUtils.copyProperties(assessment, assessmentDo);
                assessmentDo.setInfoId(dataDto.getInfoId());
                if (ObjectUtil.isEmpty(assessment.getId())) {
                    assessmentDo.setId(UUID.randomUUID().toString().replace("-", ""));
                    netMappingAssessmentMapper.insert(assessmentDo);
                } else {
                    incomingAssessmentIds.add(assessment.getId());
                    netMappingAssessmentMapper.update(assessmentDo,
                            new LambdaQueryWrapper<NetMappingAssessmentDO>()
                                    .eq(NetMappingAssessmentDO::getId, assessment.getId()));
                }
            }
        }
        Set<String> assessmentIdsToDelete = dbAssessmentIds.stream()
                .filter(id -> !incomingAssessmentIds.contains(id))
                .collect(Collectors.toSet());
        if (!assessmentIdsToDelete.isEmpty()) {
            netMappingAssessmentMapper.delete(
                    new LambdaQueryWrapper<NetMappingAssessmentDO>()
                            .in(NetMappingAssessmentDO::getId, assessmentIdsToDelete)
            );
        }

        // Host 处理逻辑
        List<NetMappingHostDO> dbHostList = netMappingHostMapper.selectList(
                new LambdaQueryWrapper<NetMappingHostDO>()
                        .eq(NetMappingHostDO::getInfoId, dataDto.getInfoId())
        );
        Set<String> dbHostIds = dbHostList.stream()
                .map(NetMappingHostDO::getId)
                .collect(Collectors.toSet());
        Set<String> incomingHostIds = new HashSet<>();

        if (ObjectUtil.isNotEmpty(hosts)) {
            for (NetMappingHostDto host : hosts) {
                NetMappingHostDO hostDo = new NetMappingHostDO();
                BeanUtils.copyProperties(host, hostDo);
                hostDo.setInfoId(dataDto.getInfoId());
                if (ObjectUtil.isEmpty(host.getId())) {
                    hostDo.setId(UUID.randomUUID().toString().replace("-", ""));
                    netMappingHostMapper.insert(hostDo);
                } else {
                    incomingHostIds.add(host.getId());
                    netMappingHostMapper.update(hostDo,
                            new LambdaQueryWrapper<NetMappingHostDO>()
                                    .eq(NetMappingHostDO::getId, host.getId()));
                }
            }
        }
        Set<String> hostIdsToDelete = dbHostIds.stream()
                .filter(id -> !incomingHostIds.contains(id))
                .collect(Collectors.toSet());
        if (!hostIdsToDelete.isEmpty()) {
            netMappingHostMapper.delete(
                    new LambdaQueryWrapper<NetMappingHostDO>()
                            .in(NetMappingHostDO::getId, hostIdsToDelete)
            );
        }
        List<NetMappingPortDO> dbPortList = netMappingPortMapper.selectList(
                new LambdaQueryWrapper<NetMappingPortDO>()
                        .eq(NetMappingPortDO::getInfoId, dataDto.getInfoId())
        );
        Set<String> dbPortIds = dbPortList.stream()
                .map(NetMappingPortDO::getId)
                .collect(Collectors.toSet());
        Set<String> incomingIds = new HashSet<>();
        if (ObjectUtil.isNotEmpty(ports)) {
            for (NetMappingPortDto port : ports) {
                NetMappingPortDO portDo = new NetMappingPortDO();
                BeanUtils.copyProperties(port, portDo);
                portDo.setInfoId(dataDto.getInfoId());
                if (ObjectUtil.isEmpty(port.getId())) {
                    // 新增
                    portDo.setId(UUID.randomUUID().toString().replace("-", "")); // 主键使用自动生成或设置
                    netMappingPortMapper.insert(portDo);
                } else {
                    // 更新
                    incomingIds.add(port.getId());
                    netMappingPortMapper.update(portDo,
                            new LambdaQueryWrapper<NetMappingPortDO>()
                                    .eq(NetMappingPortDO::getId, port.getId()));
                }
            }
        }
        Set<String> idsToDelete = dbPortIds.stream()
                .filter(id -> !incomingIds.contains(id))
                .collect(Collectors.toSet());
        if (!idsToDelete.isEmpty()) {
            netMappingPortMapper.delete(
                    new LambdaQueryWrapper<NetMappingPortDO>()
                            .in(NetMappingPortDO::getId, idsToDelete)
            );
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int Applicationdel(NetMappingDto dataDto) {
        int result = 0;
        //设置申请时间
        if (!StringUtils.isEmpty(dataDto.getInfoId())){
            //删除流程表
            LambdaQueryWrapper<ApproveProcessDO> queryWrappers = new LambdaQueryWrapper<>();
            queryWrappers.eq(ApproveProcessDO::getInfoId,dataDto.getInfoId());
            int updateCount =approveProcessMapper.delete(queryWrappers);
            //删除基础表
            LambdaQueryWrapper<NetMappingDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(NetMappingDO::getInfoId,dataDto.getInfoId());
            int deleteCount=Mapper.delete(queryWrapper);

            LambdaQueryWrapper<NetMappingHostDO> queryWrapperHost = new LambdaQueryWrapper<>();
            queryWrapperHost.eq(NetMappingHostDO::getInfoId,dataDto.getInfoId());
            int deleteHostCount= netMappingHostMapper.delete(queryWrapperHost);

            LambdaQueryWrapper<NetMappingPortDO> queryWrapperPort = new LambdaQueryWrapper<>();
            queryWrapperPort.eq(NetMappingPortDO::getInfoId,dataDto.getInfoId());
            int deletePortCount= netMappingPortMapper.delete(queryWrapperPort);

            LambdaQueryWrapper<NetMappingAssessmentDO> assessmentDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
            assessmentDOLambdaQueryWrapper.eq(NetMappingAssessmentDO::getInfoId,dataDto.getInfoId());
            int deleteAssCount= netMappingAssessmentMapper.delete(assessmentDOLambdaQueryWrapper);

            return  (updateCount > 0 || deleteCount > 0 || deleteHostCount>0|| deletePortCount>0 || deleteAssCount>0) ? 1 : 0;
        }
        return result;
    }

    @Override
    public List<NetMappingVo> queryNetMappingData(NetMappingDto dataDto) {
        List<NetMappingVo> list=new ArrayList<>();
        dataDto.setInfoType("5");
        if (!StringUtils.isEmpty(dataDto.getUserCode())){
            dataDto.setOffset(dataDto.getOffsetNum());
            list = Mapper.queryNetMappingData(dataDto);
            for (NetMappingVo NetMappingVo : list) {
                List<NetMappingHostVo> NetMappingHostVos = netMappingHostMapper.queryNetMappingHostDataById(NetMappingVo.getInfoId());
                NetMappingVo.setHosts(NetMappingHostVos);
                List<NetMappingAssessmentVo> NetMappingAssessmentVos = netMappingAssessmentMapper.queryNetMappingAssessmentDataById(NetMappingVo.getInfoId());
                NetMappingVo.setAssessments(NetMappingAssessmentVos);
                List<NetMappingPortVo> NetMappingPortVos = netMappingPortMapper.queryNetMappingPortDataById(NetMappingVo.getInfoId());
                NetMappingVo.setPorts(NetMappingPortVos);
            }
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int ApplicationSubmit(NetMappingDto dataDto) {
        int result = 0;
        //当前审批id和选择的审批用户id必传
        if (!StringUtils.isEmpty(dataDto.getExamineUserId()) && !StringUtils.isEmpty(dataDto.getProcessId())){
            //修改流程表
            LambdaQueryWrapper<ApproveProcessDO> queryWrappers = new LambdaQueryWrapper<>();
            queryWrappers.eq(ApproveProcessDO::getProcessId,dataDto.getProcessId());
            ApproveProcessDO approveProcessDO=new ApproveProcessDO();
            approveProcessDO.setProcessStatus("01");//待审核
            //修改审批表对应流程状态
            int updateCount =approveProcessMapper.update(approveProcessDO,queryWrappers);
            //新增审批表流程信息表
            ApproveProcessRecordDO approveProcessRecordDO=new ApproveProcessRecordDO();
            approveProcessRecordDO.setProcessStatus("01");//待审核第一步
            approveProcessRecordDO.setExamineUserId(dataDto.getExamineUserId());//审批用户id
            approveProcessRecordDO.setRecordId(dataDto.getProcessId());
            int deleteCount = approveProcessRecordMapper.insert(approveProcessRecordDO);
            return (updateCount > 0 || deleteCount > 0) ? 1 : 0;
        }
        return result;
    }

    @Override
    public int ApplicationWithdraw(NetMappingDto dataDto) {
        //
        int result = 0;
        if (!StringUtils.isEmpty(dataDto.getProcessStatus()) && !StringUtils.isEmpty(dataDto.getProcessId())){
            //修改当前流程为待提交
            LambdaUpdateWrapper<ApproveProcessDO> updateWrapper=new LambdaUpdateWrapper<>();
            updateWrapper.eq(ApproveProcessDO::getProcessId,dataDto.getProcessId())
                    .set(ApproveProcessDO::getProcessStatus, "00");
            int updateCount =approveProcessMapper.update(null,updateWrapper);
            //删除流程记录表
            LambdaQueryWrapper<ApproveProcessRecordDO> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(ApproveProcessRecordDO::getRecordId, dataDto.getProcessId());
            int deleteCount = approveProcessRecordMapper.delete(deleteWrapper);
            return (updateCount > 0 || deleteCount > 0) ? 1 : 0;
        }
        return result;
    }


}
